"""
增强JSON解析器
提供强大的JSON解析和修复功能，能够处理各种格式问题
"""

import json
import re
import logging
from typing import Dict, Any, Optional, List
import ast

logger = logging.getLogger(__name__)


class EnhancedJSONParser:
    """增强的JSON解析器，支持多种解析策略和自动修复"""
    
    def __init__(self):
        self.strategies = [
            self._direct_parse,
            self._clean_and_parse,
            self._extract_json_blocks,
            self._fix_common_issues,
            self._extract_test_cases_pattern,
            self._python_literal_eval,
            self._regex_extraction,
            self._fallback_parse
        ]
    
    def parse(self, content: str) -> Optional[Dict[str, Any]]:
        """
        解析JSON内容，使用多种策略
        
        Args:
            content: 要解析的内容
            
        Returns:
            解析后的字典，如果失败返回None
        """
        if not content or not content.strip():
            logger.warning("输入内容为空")
            return None
        
        content = content.strip()
        logger.info(f"开始增强JSON解析，内容长度: {len(content)}")
        
        # 依次尝试各种解析策略
        for i, strategy in enumerate(self.strategies, 1):
            try:
                result = strategy(content)
                if result and isinstance(result, dict):
                    logger.info(f"策略 {i} ({strategy.__name__}) 解析成功")
                    return result
            except Exception as e:
                logger.debug(f"策略 {i} ({strategy.__name__}) 失败: {str(e)}")
                continue
        
        logger.error("所有解析策略都失败了")
        return None
    
    def _direct_parse(self, content: str) -> Optional[Dict[str, Any]]:
        """策略1: 直接JSON解析"""
        return json.loads(content)
    
    def _clean_and_parse(self, content: str) -> Optional[Dict[str, Any]]:
        """策略2: 清理后解析"""
        # 移除markdown代码块标记
        content = re.sub(r'```json\s*', '', content)
        content = re.sub(r'```\s*$', '', content)
        
        # 移除前后的非JSON内容
        content = content.strip()
        
        # 查找第一个{和最后一个}
        start = content.find('{')
        end = content.rfind('}')
        
        if start != -1 and end != -1 and start < end:
            json_content = content[start:end+1]
            return json.loads(json_content)
        
        return None
    
    def _extract_json_blocks(self, content: str) -> Optional[Dict[str, Any]]:
        """策略3: 提取JSON块"""
        # 使用正则表达式查找JSON块
        patterns = [
            r'\{(?:[^{}]|{(?:[^{}]|{[^{}]*})*})*\}',  # 匹配嵌套的JSON对象
            r'\{[^}]*"test_cases"[^}]*\}',  # 匹配包含test_cases的简单对象
        ]
        
        for pattern in patterns:
            matches = re.findall(pattern, content, re.DOTALL)
            for match in matches:
                try:
                    result = json.loads(match)
                    if isinstance(result, dict) and 'test_cases' in result:
                        return result
                except json.JSONDecodeError:
                    continue
        
        return None
    
    def _fix_common_issues(self, content: str) -> Optional[Dict[str, Any]]:
        """策略4: 修复常见JSON问题"""
        # 修复常见的JSON格式问题
        fixes = [
            # 修复单引号
            (r"'([^']*)':", r'"\1":'),
            # 修复尾随逗号
            (r',\s*}', '}'),
            (r',\s*]', ']'),
            # 修复缺失的引号
            (r'(\w+):', r'"\1":'),
            # 修复Python的True/False/None
            (r'\bTrue\b', 'true'),
            (r'\bFalse\b', 'false'),
            (r'\bNone\b', 'null'),
        ]
        
        fixed_content = content
        for pattern, replacement in fixes:
            fixed_content = re.sub(pattern, replacement, fixed_content)
        
        try:
            return json.loads(fixed_content)
        except json.JSONDecodeError:
            return None
    
    def _extract_test_cases_pattern(self, content: str) -> Optional[Dict[str, Any]]:
        """策略5: 专门提取test_cases模式"""
        # 查找test_cases数组
        test_cases_pattern = r'"test_cases"\s*:\s*\[(.*?)\]'
        match = re.search(test_cases_pattern, content, re.DOTALL)
        
        if match:
            test_cases_content = match.group(1)
            
            # 尝试构建完整的JSON
            try:
                full_json = f'{{"test_cases": [{test_cases_content}]}}'
                return json.loads(full_json)
            except json.JSONDecodeError:
                # 尝试修复test_cases内容
                fixed_cases = self._fix_test_cases_array(test_cases_content)
                if fixed_cases:
                    return {"test_cases": fixed_cases}
        
        return None
    
    def _fix_test_cases_array(self, test_cases_content: str) -> Optional[List[Dict[str, Any]]]:
        """修复test_cases数组内容"""
        try:
            # 分割单个测试用例
            cases = []
            brace_count = 0
            current_case = ""
            
            for char in test_cases_content:
                current_case += char
                if char == '{':
                    brace_count += 1
                elif char == '}':
                    brace_count -= 1
                    if brace_count == 0:
                        # 完成一个测试用例
                        try:
                            case = json.loads(current_case.strip().rstrip(','))
                            cases.append(case)
                        except json.JSONDecodeError:
                            # 尝试修复单个用例
                            fixed_case = self._fix_single_case(current_case.strip().rstrip(','))
                            if fixed_case:
                                cases.append(fixed_case)
                        current_case = ""
            
            return cases if cases else None
            
        except Exception:
            return None
    
    def _fix_single_case(self, case_content: str) -> Optional[Dict[str, Any]]:
        """修复单个测试用例"""
        try:
            # 应用常见修复
            fixed = case_content
            
            # 修复缺失的引号
            fixed = re.sub(r'(\w+):', r'"\1":', fixed)
            
            # 修复单引号
            fixed = re.sub(r"'([^']*)'", r'"\1"', fixed)
            
            # 修复尾随逗号
            fixed = re.sub(r',\s*}', '}', fixed)
            
            return json.loads(fixed)
            
        except json.JSONDecodeError:
            return None
    
    def _python_literal_eval(self, content: str) -> Optional[Dict[str, Any]]:
        """策略6: Python字面量评估"""
        try:
            # 尝试使用ast.literal_eval解析Python字典格式
            result = ast.literal_eval(content)
            if isinstance(result, dict):
                return result
        except (ValueError, SyntaxError):
            pass
        
        return None
    
    def _regex_extraction(self, content: str) -> Optional[Dict[str, Any]]:
        """策略7: 正则表达式提取"""
        # 使用更强大的正则表达式提取
        patterns = [
            # 匹配完整的JSON对象，包含test_cases
            r'\{[^{}]*"test_cases"[^{}]*(?:\{[^{}]*\}[^{}]*)*\}',
            # 匹配更复杂的嵌套结构
            r'\{(?:[^{}]|{(?:[^{}]|{[^{}]*})*})*"test_cases"(?:[^{}]|{(?:[^{}]|{[^{}]*})*})*\}',
        ]
        
        for pattern in patterns:
            matches = re.findall(pattern, content, re.DOTALL)
            for match in matches:
                try:
                    # 尝试解析匹配的内容
                    result = json.loads(match)
                    if isinstance(result, dict) and 'test_cases' in result:
                        return result
                except json.JSONDecodeError:
                    # 尝试修复后解析
                    fixed = self._fix_common_issues(match)
                    if fixed:
                        return fixed
        
        return None
    
    def _fallback_parse(self, content: str) -> Optional[Dict[str, Any]]:
        """策略8: 回退解析 - 构建最小可用结构"""
        try:
            # 如果所有策略都失败，尝试构建一个最小的有效结构
            logger.warning("使用回退解析策略")
            
            # 查找任何看起来像测试用例的内容
            case_patterns = [
                r'"id"\s*:\s*"[^"]*"',
                r'"title"\s*:\s*"[^"]*"',
                r'"TC\d+"',
            ]
            
            found_cases = []
            for pattern in case_patterns:
                matches = re.findall(pattern, content)
                if matches:
                    # 构建一个基本的测试用例
                    case = {
                        "id": "TC001",
                        "title": "解析失败-回退用例",
                        "preconditions": "无法解析原始内容",
                        "steps": [
                            {
                                "step_number": 1,
                                "description": "请检查AI返回的JSON格式",
                                "expected_result": "修复JSON格式问题"
                            }
                        ],
                        "priority": "P3"
                    }
                    found_cases.append(case)
                    break
            
            if found_cases:
                return {"test_cases": found_cases}
            
            # 如果连基本模式都没找到，返回空结构
            return {
                "test_cases": [
                    {
                        "id": "TC001",
                        "title": "JSON解析失败",
                        "preconditions": "AI返回内容无法解析",
                        "steps": [
                            {
                                "step_number": 1,
                                "description": "检查AI模型返回的内容格式",
                                "expected_result": "返回有效的JSON格式"
                            }
                        ],
                        "priority": "P4"
                    }
                ]
            }
            
        except Exception as e:
            logger.error(f"回退解析也失败了: {str(e)}")
            return None


# 导出主要类
__all__ = ['EnhancedJSONParser']
